#include <iostream>
#include <cstring>
#include <cassert>
using namespace std;

class String
{
public:
    typedef char* iterator;
    typedef const char* const_iterator;

    size_t npos = -1;

    //全缺省构造
    String(const char* str = "")
        :_size(strlen(str))
        , _capacity(_size)
    {
        _str = new char[_size + 1]{'\0'};
        strcpy(_str, str);
    }

    //n个字符c构造
    String(size_t n, char c)
        :_size(n)
        , _capacity(n)
    {
        _str = new char[n + 1]{'\0'};
        for(int i = 0; i < n; i++) _str[i] = c;
    }

    // //拷贝构造
    // String(const String& s)
    // {
    //     _str = new char[s._capacity + 1]{'\0'};
    //     strcpy(_str, s._str);
    //     _capacity = s._capacity;
    //     _size = s._size;
    // }

    //拷贝构造
    String(const String& s)
    {
        String tmp(s._str);
        swap(tmp);
    }
    
    // //赋值重载
    // String& operator=(const String& s)
    // {
    //     if(this != &s)
    //     {
    //         delete[] _str;
    //         _str = new char[s._capacity + 1]{'\0'};
    //         strcpy(_str, s._str);
    //         _capacity = s._capacity;
    //         _size = s._size;
    //     }
    //     return *this;
    // }

    //赋值重载
    String& operator=(String s)
    {
        if(&s != this) swap(s);
        return *this;
    }

    //交换
    void swap(String& s)
    {
        std::swap(_str, s._str);
        std::swap(_size, s._size);
        std::swap(_capacity, s._capacity);
    }

    //析构
    ~String()
    {
        if(_str) delete[] _str;
        _str = nullptr;
        _size = _capacity = 0;
    }

    //增容
    void reserve(size_t n)
    {
        if(n > _capacity)
        {
            iterator tmp = _str;
            _str = new char[n + 1]{'\0'};
            strcpy(_str, tmp);
            delete[] tmp;
            _capacity = n;
        }
    }

    //插入
    void insert(size_t pos, char c)
    {
        assert(pos <= _size);
        if(_size == _capacity)
        {
            reserve(_capacity == 0 ? 4 : 2 * _capacity);
        }
        for(int i = _size + 1; i > pos; i--)
        {
            _str[i] = _str[i - 1];
        }
        _str[pos] = c;
        _size++;
    }
    void insert(size_t pos, const char* str)
    {
        assert(pos <= _size);
        size_t len = strlen(str);
        if(len == 0) return;
        if(_size + len > _capacity)
        {
            size_t newcapacity = _capacity * 2;
            if(newcapacity < _size + len)
            {
                newcapacity = _size + len;
            }
            reserve(newcapacity);
        }

        for(int i = _size + len; i > pos; i--)
        {
            _str[i] = _str[i - len];
        }
        for(int i = 0; i < len; i++)
        {
            _str[pos + i] = str[i];
        }
        _size += len;
    }

    void erase(size_t pos, size_t len)
    {
        assert(pos < _size);
        if(pos + len >= _size)
        {
            _str[pos] = '\0';
            _size = pos;
        }
        else
        {
            for(int i = 0; i < len; i++)
            {
                _str[pos + i] = _str[pos + i + len];
            }
            _size -= len;
        }
    }

    
private:
    iterator _str;
    size_t _size;
    size_t _capacity;
};